package com.ruoyi.traplight.service.impl;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.aliyun.iot20180120.Client;
import com.aliyun.iot20180120.models.*;
import com.aliyun.oss.ClientConfiguration;
import com.aliyun.tea.TeaException;
import com.aliyun.tea.TeaModel;
import com.aliyun.teautil.models.RuntimeOptions;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.permission.Dao.SerDevicePermi;
import com.ruoyi.permission.mapper.SerDevicePermiMapper;
import com.ruoyi.traplight.domain.DeviceDao;
import com.ruoyi.traplight.domain.aliyun.DeviceProperties;
import com.ruoyi.traplight.domain.aliyun.PropertyStatusInfo;
import com.ruoyi.traplight.mapper.TrapLightDeviceMapper;
import com.ruoyi.traplight.service.AliyunClientService;
import com.ruoyi.traplight.service.TrapLightDeviceService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;


@Slf4j
@Service
public class TrapLightDeviceServiceImpl extends BaseController implements TrapLightDeviceService {
    @Autowired
    TrapLightDeviceMapper deviceMapper;
    @Autowired
    AliyunClientService aliyunClientService;


    @Autowired
    private SerDevicePermiMapper permiMapper;


    private static final SimpleDateFormat SDF = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    @Override
    public boolean deleteDevice(String deviceName) {
        try {
            Client client = aliyunClientService.creatClient();
            DeleteDeviceRequest deleteDeviceRequest = new DeleteDeviceRequest()
                    .setIotInstanceId("iot-06z00hk50axjizs")
                    .setProductKey("h27jnze7JuL")
                    .setDeviceName(deviceName);
            RuntimeOptions runtime = new RuntimeOptions();
            try {
                // 复制代码运行请自行打印 API 的返回值
                DeleteDeviceResponse response = client.deleteDeviceWithOptions(deleteDeviceRequest, runtime);
                String jsonStr = com.aliyun.teautil.Common.toJSONString(TeaModel.buildMap(response.body));
                log.info(jsonStr);
                String success = getJsonResult(jsonStr, "Success");
                deviceMapper.deleteDevice(deviceName);
//                permiMapper.deleteByDeviceSerial(deviceName);
                return Objects.equals(success, "true");
            } catch (TeaException error) {
                // 如有需要，请打印 error
                com.aliyun.teautil.Common.assertAsString(error.message);
                return false;
            } catch (Exception _error) {
                TeaException error = new TeaException(_error.getMessage(), _error);
                // 如有需要，请打印 error
                com.aliyun.teautil.Common.assertAsString(error.message);
                return false;
            }
        } catch (Exception e){
            log.error(e.getMessage());
            return false;
        }
    }

    @Override
    public String getDeviceStatus(String deviceName) {
        try {
            Client client = aliyunClientService.creatClient();
            GetDeviceStatusRequest getDeviceStatusRequest = new GetDeviceStatusRequest()
                    .setDeviceName(deviceName)
                    .setIotInstanceId("iot-06z00hk50axjizs")
                    .setProductKey("h27jnze7JuL");
            RuntimeOptions runtime = new RuntimeOptions();
            try {
                // 复制代码运行请自行打印 API 的返回值
                GetDeviceStatusResponse response = client.getDeviceStatusWithOptions(getDeviceStatusRequest, runtime);
                String jsonStr = com.aliyun.teautil.Common.toJSONString(TeaModel.buildMap(response.body));
                if (Objects.equals(getJsonResult(jsonStr, "Success"), "true")){
                    String onlineState = getJsonResult(getJsonResult(jsonStr, "Data"), "Status").equals("ONLINE")?"在线":"离线";
                    DeviceDao deviceDao = deviceMapper.selectDeviceByName(deviceName).setDeviceStatus(onlineState);
                    deviceMapper.updateDevice(deviceDao);
                    //更新全部设备表中测报灯设备的信息
                    String nickName = deviceDao.getNickName();
//                    Date updateTime = deviceDao.getUpdateTime();
                    String area = deviceDao.getArea();
//                    AllDeviceInfo allDeviceInfo = deviceInfoMapper.selectDeviceByDeviceSerial(deviceName);
//                    allDeviceInfo.setOnlineState(onlineState);
//                    allDeviceInfo.setName(nickName);
//                    allDeviceInfo.setUpdateTime(updateTime);
//                    allDeviceInfo.setArea(area);
//                    deviceInfoMapper.updateDevice(allDeviceInfo);
                    //更新权限表里的测报灯设备信息
                    if(permiMapper.selectByDeviceSerial(deviceName)!=null) {
                        SerDevicePermi devicePermiInfo = permiMapper.selectByDeviceSerial(deviceName);
                        devicePermiInfo.setArea(area);
                        devicePermiInfo.setDeviceName(nickName);
                        devicePermiInfo.setOnlineState(onlineState);
                        permiMapper.updateByPrimaryKeySelective(devicePermiInfo);
                    }
                    return onlineState;
                } else {
                    return null;
                }
            } catch (TeaException error) {
                // 如有需要，请打印 error
                com.aliyun.teautil.Common.assertAsString(error.message);
                return null;
            } catch (Exception _error) {
                TeaException error = new TeaException(_error.getMessage(), _error);
                // 如有需要，请打印 error
                com.aliyun.teautil.Common.assertAsString(error.message);
                return null;
            }
        } catch (Exception e){
            log.error(e.getMessage());
            return null;
        }
    }

    @Override
    public String invokeThingService(String deviceName, String identifier, String args) {
        try {
            // 设置连接超时时间为 5 秒
            System.setProperty("sun.net.client.defaultConnectTimeout", "180000");
            // 设置读取超时时间为 10 秒
            System.setProperty("sun.net.client.defaultReadTimeout", "180000");
            Client client = aliyunClientService.creatClient();
            InvokeThingServiceRequest invokeThingServiceRequest = new InvokeThingServiceRequest()
                    .setIotInstanceId("iot-06z00hk50axjizs")
                    .setProductKey("h27jnze7JuL")
                    .setDeviceName(deviceName)
                    .setIdentifier(identifier)
                    .setArgs(args);
            RuntimeOptions runtime = new RuntimeOptions();

            try {
                // 复制代码运行请自行打印 API 的返回值
                InvokeThingServiceResponse response = client.invokeThingServiceWithOptions(invokeThingServiceRequest, runtime);
                log.info(response.toString());
                String jsonStr = com.aliyun.teautil.Common.toJSONString(TeaModel.buildMap(response.body));
                log.info(jsonStr);
                if (Objects.equals(getJsonResult(jsonStr, "Success"), "true")){

                    return getJsonResult(getJsonResult(jsonStr, "Data"), "MessageId");
                } else {
                    return null;
                }
            } catch (TeaException error) {
                // 如有需要，请打印 error
                com.aliyun.teautil.Common.assertAsString(error.message);
                return null;
            } catch (Exception _error) {
                TeaException error = new TeaException(_error.getMessage(), _error);
                // 如有需要，请打印 error
                com.aliyun.teautil.Common.assertAsString(error.message);
                return null;
            }
        } catch (Exception e){
            log.error(e.getMessage());
            return null;
        }
    }

    @Override
    public String setDeviceProperty(String deviceName, String jsonString) {
        try {
            Client client = aliyunClientService.creatClient();
            SetDevicePropertyRequest setDevicePropertyRequest = new SetDevicePropertyRequest()
                    .setIotInstanceId("iot-06z00hk50axjizs")
                    .setProductKey("h27jnze7JuL")
                    .setDeviceName(deviceName)
                    .setItems(jsonString);
            RuntimeOptions runtime = new RuntimeOptions();
            try {
                // 复制代码运行请自行打印 API 的返回值
                SetDevicePropertyResponse response = client.setDevicePropertyWithOptions(setDevicePropertyRequest, runtime);
                String jsonStr = com.aliyun.teautil.Common.toJSONString(TeaModel.buildMap(response.body));
//                log.info(jsonStr);
                if (Objects.equals(getJsonResult(jsonStr, "Success"), "true")){
                    return getJsonResult(getJsonResult(jsonStr,"Data"),"MessageId");
                }else {
                    return null;
                }
            } catch (TeaException error) {
                // 如有需要，请打印 error
                com.aliyun.teautil.Common.assertAsString(error.message);
                return null;
            } catch (Exception _error) {
                TeaException error = new TeaException(_error.getMessage(), _error);
                // 如有需要，请打印 error
                com.aliyun.teautil.Common.assertAsString(error.message);
                return null;
            }
        } catch (Exception e){
            log.error(e.getMessage());
            return null;
        }
    }

    @Override
    public DeviceDao getDeviceName(String deviceMac) {
        try {
            DeviceDao deviceDao = deviceMapper.selectDeviceByMac(deviceMac);
            if (deviceDao != null){
                return deviceDao;
            } else {
                Client client = aliyunClientService.creatClient();
                RegisterDeviceRequest registerDeviceRequest = new RegisterDeviceRequest()
                        .setIotInstanceId("iot-06z00hk50axjizs")
                        .setProductKey("h27jnze7JuL")
                        .setNickname(deviceMac);
                RuntimeOptions runtime = new RuntimeOptions();
                try {
                    RegisterDeviceResponse response = client.registerDeviceWithOptions(registerDeviceRequest, runtime);
                    String jsonStr = com.aliyun.teautil.Common.toJSONString(TeaModel.buildMap(response.body));
                    log.info(jsonStr);
                    String successCode = getJsonResult(jsonStr,"Success");
                    JSONObject jsonObject = JSON.parseObject(jsonStr);
                    if (Objects.equals(successCode, "true")){
                        String data = jsonObject.get("Data").toString();
                        JSONObject dataObject = JSON.parseObject(data);
                        String deviceName = dataObject.get("DeviceName").toString();
                        String deviceSecret = dataObject.get("DeviceSecret").toString();
                        DeviceDao newDeviceDao = new DeviceDao().setDeviceMac(deviceMac)
                            .setDeviceName(deviceName)
                            .setDeviceSecret(deviceSecret);

                        log.info(String.valueOf(newDeviceDao));
                        int flag = deviceMapper.insertDevice(newDeviceDao);
                        if (flag == 1){
                            Integer deviceNo = deviceMapper.selectDeviceByName(deviceName).getDeviceId();
                            SerDevicePermi serDevicePermi = new SerDevicePermi().setDeviceSerial(deviceName).setDeviceType("虫情测报灯").setTypeId(1).setDeviceNo(deviceNo);
                            permiMapper.insert(serDevicePermi);
                            return newDeviceDao;
                        } else {
                            return null;
                        }
                    } else {
                        return null;
                    }
                } catch (TeaException error) {
                    // 如有需要，请打印 error
                    com.aliyun.teautil.Common.assertAsString(error.message);
                    return null;
                } catch (Exception _error) {
                    TeaException error = new TeaException(_error.getMessage(), _error);
                    // 如有需要，请打印 error
                    com.aliyun.teautil.Common.assertAsString(error.message);
                    return null;
                }
            }
        } catch (Exception e){
            log.error(e.getMessage());
            return null;
        }
    }

    @Override
    public DeviceProperties getDeviceProperties(String deviceName) {
        try {
            DeviceDao deviceDao = deviceMapper.selectDeviceByName(deviceName);
            if (deviceDao == null){
                return null;
            }
            Client client = aliyunClientService.creatClient();
            QueryDevicePropertyStatusRequest queryDevicePropertyStatusRequest = new QueryDevicePropertyStatusRequest()
                    .setIotInstanceId("iot-06z00hk50axjizs")
                    .setProductKey("h27jnze7JuL")
                    .setDeviceName(deviceDao.getDeviceName());
            RuntimeOptions runtime = new RuntimeOptions();
            try {
                // 复制代码运行请自行打印 API 的返回值
                QueryDevicePropertyStatusResponse response =
                        client.queryDevicePropertyStatusWithOptions(queryDevicePropertyStatusRequest, runtime);
                String jsonStr = com.aliyun.teautil.Common.toJSONString(TeaModel.buildMap(response.body));
                log.info("jsonStr:" + jsonStr);
                if (Objects.equals(getJsonResult(jsonStr, "Success"), "true")){
                    String statusInfo = getJsonResult(getJsonResult(jsonStr, "Data"), "List");
                    JSONArray array = JSON.parseArray(getJsonResult(statusInfo, "PropertyStatusInfo"));
                    DeviceProperties deviceProperties = new DeviceProperties();
                    List<PropertyStatusInfo> infos = array.toList(PropertyStatusInfo.class);
                    log.info(infos.toString());
                    deviceProperties.setDeviceId(deviceDao.getDeviceId());
                    deviceProperties.setDeviceName(deviceDao.getDeviceName());
                    deviceProperties.setWorkMode(Integer.parseInt(infos.get(0).getValue()));
                    deviceProperties.setWorkModeTime(getTimeFormat(infos,0));
                    deviceProperties.setRainStatus(Integer.parseInt(infos.get(1).getValue()));
                    deviceProperties.setRainStatusTime(getTimeFormat(infos,1));
                    deviceProperties.setRainWorkMode(Integer.parseInt(infos.get(2).getValue()));
                    deviceProperties.setRainWorkModeTime(getTimeFormat(infos,2));
                    deviceProperties.setPhotoParams(JSON.parseObject(infos.get(3).getValue(), DeviceProperties.PhotoParams.class));
                    deviceProperties.setPhotoParamsTime(getTimeFormat(infos,3));
                    deviceProperties.setGeoLocation(JSON.parseObject(infos.get(4).getValue(), DeviceProperties.GeoLocation.class));
                    deviceProperties.setGeoLocationTime(getTimeFormat(infos,4));
                    deviceProperties.setProduceInfo(JSON.parseObject(infos.get(5).getValue(), DeviceProperties.ProduceInfo.class));
                    deviceProperties.setProduceInfoTime(getTimeFormat(infos,5));
                    deviceProperties.setBatteryPercentage(Double.parseDouble(infos.get(6).getValue()));
                    deviceProperties.setBatteryPercentageTime(getTimeFormat(infos,6));
                    deviceProperties.setLightStatus(Integer.parseInt(infos.get(7).getValue()));
                    deviceProperties.setLightStatusTime(getTimeFormat(infos,7));
                    deviceProperties.setTimeModeSet(JSON.parseArray(infos.get(8).getValue(), DeviceProperties.TimeModeSet.class));
                    deviceProperties.setTimeModeSetTime(getTimeFormat(infos,8));
                    deviceProperties.setDormantModeSet(JSON.parseObject(infos.get(9).getValue(), DeviceProperties.DormantModeSet.class));
                    deviceProperties.setDormantModeSetTime(getTimeFormat(infos,9));
                    deviceProperties.setSeasonSet(JSON.parseArray(infos.get(10).getValue(), DeviceProperties.SeasonSet.class));
                    deviceProperties.setSeasonSetTime(getTimeFormat(infos,10));
                    deviceProperties.setEngineeringMode(JSON.parseObject(infos.get(11).getValue(), DeviceProperties.EngineeringMode.class));
                    deviceProperties.setEngineeringModeTime(getTimeFormat(infos,11));
                    deviceProperties.setTemperature(Float.parseFloat(infos.get(12).getValue()));
                    deviceProperties.setTemperatureTime(getTimeFormat(infos,12));
                    deviceProperties.setWarnSetting(JSON.parseObject(infos.get(13).getValue(), DeviceProperties.WarnSetting.class));
                    deviceProperties.setWarnSettingTime(getTimeFormat(infos,13));
                    log.info(deviceProperties.toString());
                    return deviceProperties;
                } else {
                    return null;
                }
            } catch (TeaException error) {
                // 如有需要，请打印 error
                com.aliyun.teautil.Common.assertAsString(error.message);
                return null;
            } catch (Exception _error) {
                TeaException error = new TeaException(_error.getMessage(), _error);
                // 如有需要，请打印 error
                com.aliyun.teautil.Common.assertAsString(error.message);
                return null;
            }
        } catch (Exception e){
            log.error(e.getMessage());
            return null;
        }
    }

    public List<Integer> selectDeviceIdByarea(String area){
        return deviceMapper.selectDeviceIdByArea(area);
    }

    @Override
    public TableDataInfo selectDeviceInfoByCondition(DeviceDao deviceDao,List<SerDevicePermi> serDevicePermiList) {
        startPage();
        List<DeviceDao> deviceDaos = deviceMapper.selectDeviceInfoByCondition(deviceDao);
        if(!serDevicePermiList.isEmpty()) {
            deviceDaos = deviceDaos.stream()
                    .filter(filteredDevcieDao -> serDevicePermiList.stream()
                            .anyMatch(serDevicePermi -> serDevicePermi.getDeviceNo().equals(filteredDevcieDao.getDeviceId())))
                    .collect(Collectors.toList());
        }
        return getDataTable(deviceDaos);
    }
    /**
     * JSON解析
     * @author FLInt
     * @date 2021/11/27 14:06
     * @param dataString json字符串
     * @param key 解析的key
     * @return java.lang.String
     */
    private String getJsonResult(String dataString, String key){
        JSONObject jsonObject = JSONObject.parseObject(dataString);
        return jsonObject.get(key).toString();
    }

    private String getTimeFormat(List<PropertyStatusInfo> infos, int num){
        return SDF.format(new Date(new Long(infos.get(num).getTime())));
    }

}
